/*
	Copyright (C) 2010 2011 Rémi Thebault

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <procycle/macrotask.h>
#include <procycle/atomtask.h>

#include "tasktreeitem.h"


TaskTreeItem::TaskTreeItem(PC::Task* task, TaskTreeItem* parent)
:	m_task(task)
,	m_parent(parent)
{
	PC::MacroTask* mt = dynamic_cast<PC::MacroTask*>(task);
	if (mt) {
		for(PC::Task::const_iterator ti=mt->taskBegin();
				ti != mt->taskEnd(); ++ti) {
			m_children.append(new TaskTreeItem(*ti, this));
		}
	}
}


QVariant
TaskTreeItem::data(PC::Task::Data td) const {
	if (m_task) {
		switch(td) {
		case PC::Task::DATA_NUM:
			return m_task->num();
		case PC::Task::DATA_TBSID:
			return m_task->tbsId();
		case PC::Task::DATA_POS:
			return m_task->pos();
		case PC::Task::DATA_NAME:
			return m_task->name();
		case PC::Task::DATA_LENGTH:
			return m_task->length();
		case PC::Task::DATA_START:
			return m_task->start();
		case PC::Task::DATA_FINISH:
			return m_task->finish();
		case PC::Task::DATA_LATESTART:
			return m_task->lateStart();
		case PC::Task::DATA_LATEFINISH:
			return m_task->lateFinish();
		case PC::Task::DATA_PREDECESSORS:
			//TODO: implement predecessors string
			return QVariant();
		case PC::Task::DATA_COLOR:
		case PC::Task::DATA_COUNT:
			return QVariant();
		}
	}
	return QVariant();
}


bool TaskTreeItem::setData(PC::Task::Data td, QVariant value) {
    switch (td) {
    case PC::Task::DATA_NAME:
        m_task->setName(value.toString());
        return true;
    case PC::Task::DATA_LENGTH: {
            PC::AtomTask* at = dynamic_cast<PC::AtomTask*>(m_task);
            if (at) {
                at->setLength(value.toInt());
            }
        }
        return true;
    default:
        break;
    }
    return false;
}


bool AppendTaskTreeItem::setData(PC::Task::Data td, QVariant value) {
    switch (td) {
    case PC::Task::DATA_NAME: {
            PC::Task *t = m_cycle->createAndAppendTask();
            t->setName(value.toString());
            m_cycle->setNum(0);
        }
        return true;
    case PC::Task::DATA_LENGTH: {
            PC::AtomTask *at = static_cast<PC::AtomTask*>(
                        m_cycle->createAndAppendTask());
            at->setLength(value.toInt());
            m_cycle->setNum(0);
        }
        return true;
    default:
        break;
    }
    return false;
}


Qt::ItemFlags
TaskTreeItem::flags(PC::Task::Data td) const {
    switch (td) {
    case PC::Task::DATA_NAME:
        return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    case PC::Task::DATA_LENGTH: {
            if (dynamic_cast<PC::AtomTask*>(m_task)) {
                return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
            }
        }
        break;
    default:
        break;
    }
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

TaskTreeItem*
TaskTreeItem::resolvItem(QString r_tbsId) {
	bool ok;
	int point = r_tbsId.indexOf('.');
	if (point == -1) {
		int pos = r_tbsId.toInt(&ok);
		if (!ok || pos < 0 || pos >= m_children.size()) {
			return 0;
		}
		return m_children.at(pos);
	}
	QString befPoint = r_tbsId.left(point);
	QString aftPoint = r_tbsId.right(r_tbsId.length() - (point+1));
	int pos = befPoint.toInt(&ok);
	if (!ok || pos < 0 || pos >= m_children.size()) {
		return 0;
	}
	return m_children.at(pos)->resolvItem(aftPoint);
}

Qt::ItemFlags
AppendTaskTreeItem::flags(PC::Task::Data td) const {
    switch (td) {
    case PC::Task::DATA_NAME:
    case PC::Task::DATA_LENGTH:
        return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    default:
        break;
    }
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
